import fg from 'fast-glob';
import fs from 'fs-extra';
import path from 'path';
import qrcode from 'qrcode';
import { BuildParams } from "./BuildParams.js";
import { CmdOption } from "./CmdOption.js";
import { PlatformCfgParser } from './cfg/PlatformCfgParser.js';
import { PkgType, ChannelCfg } from './typings';
import { getModifyTime } from './tools/vendor.js';

export class HtmlMaker {

    private readonly indexhtml = `
<html><head><title>apks download</title></head>
<body>
<script>
var s = '<iframe src="apklist.html?v=' + (new Date()).getTime() + '" width="100%" height="100%" style="border:none;"></iframe>';
document.write(s);
</script>
</body>
</html>
`;
    private readonly apkitem = '<a class="apk" href="{apk}" onmouseout="hiddenPic();" onmousemove="showPic(event, \'{qrcode}\');">{apk} - <font class=time1>{createtime}</font></a>&nbsp;&nbsp;<a class="copy" onclick="copyApkUrl(\'{url}\')"/>复制外网下载地址</a>&nbsp;'
    private readonly listhtml = `
<!DOCTYPE html>
<html>
<head>
<title>安卓安装包列表</title>
<style type="text/css">
BODY {font-family:'Microsoft YaHei',Tahoma,Arial,sans-serif;color:black;background-color:white;font-size:14px;} 
a.apk:link {color:black;text-decoration:underline;}
a.apk:visited {color:black;text-decoration:underline;}
a.apk:hover {color:red;text-decoration:underline;}

a.more:link {color:gray;text-decoration:none;}
a.more:visited {color:gray;text-decoration:none;}
a.more:hover {color:red;text-decoration:none;}

a.copy:link {color:gray;text-decoration:none;}
a.copy:visited {color:gray;text-decoration:none;}
a.copy:hover {color:red;text-decoration:none;}

.line1 {height: 2px; width:900px; background-color: #525D76; border: none;}
.line2 {height: 1px; width:900px; background-color: #725D76; border: none;}
.line3 {height: 1px; width:900px; border: none; border-top:1px dotted #ddd;}
.t1{background:white;color:black;font-size:18px;}
.time1{background:white;color:black;font-size:12px;}
</style> 
</head>
<body>
<script>
var lastid = -1;
function toggleMore(id) {
  if (lastid != -1 && lastid != id) {
    document.getElementById('id_' + lastid).style.display = 'none';
    document.getElementById('btn_' + lastid).text = '更多';
  }
  var moreapks = document.getElementById('id_' + id);
  var morebtn = document.getElementById('btn_' + id);
  if (moreapks.style.display == 'none') {
    moreapks.style.display = 'block';
    morebtn.text = '收起';
  } else {
    moreapks.style.display = 'none';
    morebtn.text = '更多';
  }
  lastid = id;
}
var copyInput = null;
function copyApkUrl(url) {
  if (window.copy) {
    window.copy(url);
    alert("外网地址复制成功!");
  } else if (window.clipboardData) {
    window.clipboardData.setData("Text",url);
    alert("外网地址复制成功!");
  } else {
    try {
      if (copyInput == null) {
        copyInput = document.createElement('input');
        copyInput.style.zIndex = "-1000";
        copyInput.style.left = "-10000px";
        copyInput.style.position = "absolute";
        document.body.appendChild(copyInput);
      }
      copyInput.value = url;
      copyInput.select();
      document.execCommand("Copy");
      alert("外网地址复制成功!");
    } catch (e) {
      alert("外网地址为：" + url);
    }
  }  
}
</script>
<script language="javascript">
    function showPic(e,sUrl){
        var x,y;
        x = e.clientX;
        y = e.clientY;
        document.getElementById('qrcodeImg').style.left = x+2+'px';
        document.getElementById('qrcodeImg').style.top = y+2+'px';
        document.getElementById('qrcodeImg').innerHTML = "<img border='0' src=" + sUrl + ">";
        document.getElementById('qrcodeImg').style.display = "";
    } 
    function hiddenPic(){
        document.getElementById('qrcodeImg').innerHTML = "";
        document.getElementById('qrcodeImg').style.display = "none"
    }
</script>
<center>
<div id="qrcodeImg" style="display: none; position: absolute; z-index: 100;"></div>
<hr class="line1">
{apks}
<hr class="line1">
</center>
</body>
</html>
`;

    private readonly testGameId = 3;

    /**记录apk url */
    public readonly apkUrlMapper: Record<string, string> = {};

    public async exportPkgsListHtml(apkpath: string, option: CmdOption, params: BuildParams, platCfgParser: PlatformCfgParser, pkgType: PkgType, patterns: string[]): Promise<void> {
        console.log(`exportPkgsListHtml: ${apkpath}`);

        const allCfgs = platCfgParser.getAll();
        // 获取平台测试包的cdn地址
        let testPkgCdn = allCfgs!.find(item=> item.gameid == this.testGameId)?.url??"";

        let id = 0;
        let apks = '';
        console.log('@@ export pkgs list html:', params.qrcodeUrl);
        if (params.channelCfg[pkgType])
            apks = await this._exportOneChannelApks(apkpath, params.qrcodeUrl, params.channelCfg, id, pkgType, patterns, testPkgCdn);
        id++;

        apks = apks + '<br/><hr class="line1"><p>所有渠道包</p>\n';

        
        for (let channelcfg of allCfgs!) {
            if (!channelcfg[pkgType]) continue;
            apks = apks + await this._exportOneChannelApks(apkpath, params.qrcodeUrl, channelcfg, id, pkgType, patterns, testPkgCdn);
            id++;
        }

        const s = this.listhtml.replace('{apks}', apks);
        fs.ensureDir(apkpath);
        fs.writeFileSync(path.join(apkpath, 'apklist.html'), s, 'utf-8');
        fs.writeFileSync(path.join(apkpath, 'index.html'), this.indexhtml, 'utf-8');
    }

    private async _exportOneChannelApks(apkpath: string, qrcodeUrl: string, channelCfg: ChannelCfg, id: number, pkgType: PkgType, patterns: string[], testPkgCdn: string) {
        let apks = '';
        const files = await fg(patterns, { cwd: apkpath, caseSensitiveMatch: false, absolute: true });
        const apkfiles = this._getApks(files, channelCfg[pkgType]!, pkgType);
        if (!apkfiles.length)
            return apks;

        const title = channelCfg['platName'] + ' · ' + channelCfg['productName'];
        apks = apks + `<hr class="line2"><p>${title}</p><hr class="line3">\n`;
        let index = 0;
        for (let apkfile of apkfiles) {
            let t = getModifyTime(apkfile);
            const basefile = path.basename(apkfile);
            const basename = path.basename(apkfile, path.extname(apkfile));
            if (index == 1)
                apks = apks + `<div id="id_${id}" style="display:none;">`;

            const qrcodeImgFile = basename + '.png';
            await qrcode.toFile(path.join(apkpath, qrcodeImgFile), qrcodeUrl + basefile);

            let apkurl = channelCfg.url + pkgType + '/' + channelCfg['path'] + '/' + basefile;
            if (channelCfg.gameid > this.testGameId && testPkgCdn) {
              apkurl = testPkgCdn + pkgType + '/' + channelCfg['path'] + '/' + basefile;
            }
            this.apkUrlMapper[basefile] = apkurl;
            const apkitemstr = this.apkitem.replace(/\{apk\}/g, basefile).replace(/\{createtime\}/g, t).replace(/\{qrcode\}/g, qrcodeImgFile).replace(/\{url\}/g, apkurl);
            if (index == 0 && apkfiles.length > 1)
                apks = apks + '<p>' + apkitemstr + `&nbsp;&nbsp;<a class="more" id="btn_${id}" onclick="toggleMore(${id})"/>更多</a></p>\n`;
            else
                apks = apks + '<p>' + apkitemstr + '</p>\n';

            if (index == apkfiles.length - 1)
                apks = apks + '</div>';
            index++;
        }

        return apks;
    }

    private _getApks(files: string[], apkpatt: string, pkgType: PkgType): string[] {
        if (pkgType == 'exe') {
            // PC包名为xxx.pc.01234.zip
            apkpatt += '\\.pc\\.(\\d{5})';
        } else {
            // 手游的包名为com.xxx.yyy.zzz.v1.0.0.1001.apk
            apkpatt = apkpatt.replace('{version}', '(\\d+\\.\\d+\\.\\d+\\.\\d+)(\\(\\d+\\))?').replace(".aab", ".(aab|apk)");
        }
        let apkpattRegexp = new RegExp(apkpatt);
        let matchapks: string[] = [];
        // let file2Ver: {[file: string]: number} = {};
        let file2Mtime: { [file: string]: number } = {};
        for (let file of files) {
            const basefile = path.basename(file);
            let matchRst = basefile.match(apkpattRegexp);
            if (matchRst) {
                matchapks.push(file);
                file2Mtime[file] = fs.statSync(file).mtime.getTime();
            }
        }

        // matchapks.sort((a: string, b: string)=>{return file2Ver[b] - file2Ver[a]});
        // 版本号可能因各种原因出现混乱，改为按修改时间排序
        matchapks.sort((a: string, b: string) => { return file2Mtime[b] - file2Mtime[a] });
        return matchapks;
    }
}